home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-02 / pas_all.zip / TI1230.ASC < prev    next >
Text File  |  1993-01-25  |  14KB  |  529 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.   PRODUCT  :  Paradox Engine                        NUMBER  :  1230
  9.   VERSION  :  3.0
  10.        OS  :  DOS/WIN
  11.      DATE  :  January 25, 1993                         PAGE  :  1/8
  12.  
  13.     TITLE  :  Workaround for PXSrchFld RecNotFound Problem
  14.  
  15.  
  16.  
  17.  
  18.  
  19.   {
  20.     It has been brought to our attention that doing a PXSrchFld
  21.     with either the SEARCHFIRST or CLOSESTRECORD parameter will
  22.     fail in certain circumstances.   Our QA department has an
  23.     example of this and is working on a solution.
  24.  
  25.     We have created this workaround to use in the meantime. The
  26.     workaround is to do a CLOSESTRECORD search in place of the
  27.     SEARCHFIRST search. A CLOSESTRECORD search will leave the
  28.     record cursor on the first record that has a value greater than
  29.     the search value and return PXERR_RECNOTFOUND if an exact match
  30.     is not found. In some cases a CLOSESTRECORD search will treat
  31.     an exact match as the first value greater than the search value
  32.     (the problem that we are trying to get around).
  33.  
  34.     What this workaround does is manually compare the search value
  35.     to the value in the current record when PXERR_RECNOTFOUND is
  36.     returned.
  37.  
  38.  
  39.     How to use this function:
  40.     =========================
  41.  
  42.     Put this unit after the PXEngine unit in your USES clause.
  43.     This will cause the PXSrchFld in this unit to be called instead
  44.     of the original PXSrchFld in the PXEngine unit to be called.
  45.  
  46.     You can define the variable DEBUG in order to determine when
  47.     you enter the special parts of the PXSrch function, using
  48.     either -DDEBUG at the command line while compiling, or under
  49.     'Options | Compiler | Conditional defines - in the IDE.
  50.  
  51.  
  52.     Using with the Database Framework ( DBF ):
  53.     ==========================================
  54.  
  55.     You will need to recompile the Database Framework with the
  56.     corrections to the USES clause ( see above ).
  57.  
  58.  
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73.  
  74.   PRODUCT  :  Paradox Engine                        NUMBER  :  1230
  75.   VERSION  :  3.0
  76.        OS  :  DOS/WIN
  77.      DATE  :  January 25, 1993                         PAGE  :  2/8
  78.  
  79.     TITLE  :  Workaround for PXSrchFld RecNotFound Problem
  80.  
  81.  
  82.  
  83.  
  84.     Differences between SrchFld.PXSrchFld and PXEngine.PXSrchFld:
  85.  
  86.       1) SrchFld.PXSrchFld will move the current record cursor as
  87.          described for a CLOSESTRECORD search when doing a
  88.          SEARCHFIRST.
  89.  
  90.       2) A number of different error messages could be returned
  91.          because of all the engine calls that occur in PXEngine.
  92.          PXSrchFld that would not be returned from
  93.          SrchFld.PXSrchFld.
  94.  
  95.       3) A SEARCHFIRST can return PXERR_ENDOFTABLE in
  96.          SrchFld.PXSrch, which it would not in PXEngine.PXSrchFld.
  97.          The reason for this is to let you know when the record
  98.          cursor is at the end of the table, not at the first record
  99.          greater than the value that you are searching for.  You
  100.          can change this behavior by searching for PXERR_ENDOFTABLE
  101.          and uncomment the
  102.                     'SrchFld := PXERR_RECNOTFOUND ) ;
  103.                      Exit;'
  104.          statements.
  105.  
  106.  
  107.          Limitations:
  108.          SrchFld.PXSrchFld will not work on composite or case
  109.          insensitive indexes, where it returns PXERR_INVFIELDHANDLE
  110.          (which can be at the beginning or SrchFld.PXSrchFld).
  111.          There is no way for us to determine which fields are part
  112.          of a composite secondary index (or of a case insensitive
  113.          index). What is needed is a routine similar to
  114.          SrchFld.PXSrchFld that knows which fields are part of
  115.          your secondary index and does the manual comparison on
  116.          those fields (on a case-insensitive index).
  117.   }
  118.  
  119.   unit srchfld;
  120.   {$N+,E+}
  121.  
  122.   interface
  123.   uses
  124.  
  125.  
  126.  
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.   PRODUCT  :  Paradox Engine                        NUMBER  :  1230
  141.   VERSION  :  3.0
  142.        OS  :  DOS/WIN
  143.      DATE  :  January 25, 1993                         PAGE  :  3/8
  144.  
  145.     TITLE  :  Workaround for PXSrchFld RecNotFound Problem
  146.  
  147.  
  148.  
  149.  
  150.   {$ifdef Windows}
  151.     PXEngWin,
  152.     Strings;
  153.   {$else}
  154.     PxEngine;
  155.   {$endif}
  156.  
  157.   function PXSrchFld(TblHandle : TableHandle;
  158.                      RecHandle : RecordHandle;
  159.                      FldHandle : FieldHandle;
  160.                      Mode : integer) : integer;
  161.  
  162.  
  163.   implementation
  164.  
  165.   const
  166.     SigFig = 0.00000000000001;
  167.  
  168.   function PXSrchFld(TblHandle : TableHandle;
  169.                      RecHandle : RecordHandle;
  170.                      FldHandle : FieldHandle;
  171.                      Mode : integer) : integer;
  172.   var
  173.     pxErr : integer;
  174.     RecHandleTemp : RecordHandle;
  175.   {$ifdef Windows}
  176.     FldType : array [0..6] of char;
  177.   {$else}
  178.     FldType : NameString;
  179.   {$endif}
  180.     StrFld1, StrFld2 : String;
  181.     CharFld1, CharFld2 : array [0..255] of char;
  182.     DateFld1, DateFld2 : TDate;
  183.     NumFld1, NumFld2 : Double;
  184.     ShortFld1, ShortFld2 : Integer;
  185.   begin
  186.  
  187.     { This function cannot handle composite/case-insensitive index}
  188.     if (FldHandle > 255) then begin
  189.       PXSrchFld := PXErr_InvFieldHandle;
  190.  
  191.  
  192.  
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204.  
  205.  
  206.   PRODUCT  :  Paradox Engine                        NUMBER  :  1230
  207.   VERSION  :  3.0
  208.        OS  :  DOS/WIN
  209.      DATE  :  January 25, 1993                         PAGE  :  4/8
  210.  
  211.     TITLE  :  Workaround for PXSrchFld RecNotFound Problem
  212.  
  213.  
  214.  
  215.  
  216.       exit;
  217.     end;
  218.  
  219.     {$ifdef Windows}
  220.     pxErr := pxengwin.PXSrchFld(TblHandle, RecHandle,
  221.                                 FldHandle, Mode);
  222.     {$else}
  223.     pxErr := pxengine.PXSrchFld(TblHandle, RecHandle,
  224.                                 FldHandle, Mode);
  225.     {$endif}
  226.  
  227.     case Mode of
  228.  
  229.       SearchNext : begin
  230.         { SearchNext Works }
  231.         PXSrchFld := pxErr;
  232.         Exit;
  233.       end;
  234.  
  235.       SearchFirst, ClosestRecord : begin
  236.         { Record found - everything OK }
  237.         if pxErr = pxSuccess then begin
  238.           PXSrchFld := pxErr;
  239.           exit;
  240.         end else
  241.           { see if record really not there }
  242.           if pxErr = pxErr_RecNotFound then begin
  243.             {$ifdef debug}
  244.               writeln('Using special PXSrchFld operation');
  245.             {$endif}
  246.             {$ifdef Windows}
  247.             pxErr := PXFldType(TblHandle, FldHandle, 6, FldType);
  248.             {$else}
  249.             pxErr := PXFldType(TblHandle, FldHandle, FldType);
  250.             {$endif}
  251.             if pxErr <> PXSuccess then begin
  252.               PXSrchFld := pxErr;
  253.               exit;
  254.             end;
  255.  
  256.  
  257.  
  258.  
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
  271.  
  272.   PRODUCT  :  Paradox Engine                        NUMBER  :  1230
  273.   VERSION  :  3.0
  274.        OS  :  DOS/WIN
  275.      DATE  :  January 25, 1993                         PAGE  :  5/8
  276.  
  277.     TITLE  :  Workaround for PXSrchFld RecNotFound Problem
  278.  
  279.  
  280.  
  281.  
  282.             { open a local temporary record buffer }
  283.             pxErr := PXRecBufOpen(TblHandle, RecHandleTemp);
  284.             if pxErr <> pxSuccess then begin
  285.               PXSrchFld := pxErr;
  286.               exit;
  287.             end;
  288.             { Get the current rec and save to new record handle }
  289.             pxErr := PXRecGet(TblHandle, RecHandleTemp);
  290.             if pxErr <> pxSuccess then begin
  291.               PXRecBufClose(RecHandleTemp);
  292.               PXSrchFld := pxErr;
  293.               exit;
  294.             end;
  295.  
  296.             { do a manual comparison using the following steps: }
  297.             { Get the value from the passed in record buffer }
  298.             case FldType[1] of
  299.               'A' : begin
  300.               {$ifDef Windows}
  301.                 pxErr := PXGetAlpha(RecHandle, FldHandle,
  302.                                     256, CharFld1);
  303.                 if pxErr = pxSuccess then begin
  304.                   pxErr := PXGetAlpha(RecHandleTemp, FldHandle,
  305.                                       256, CharFld2);
  306.                   if pxErr = pxSuccess then begin
  307.                     { close temp record buffer }
  308.                     PXRecBufClose(RecHandleTemp);
  309.  
  310.                 if (StrComp(CharFld1, CharFld2) = 0) then
  311.                       PXSrchFld := pxSuccess
  312.                     else
  313.                       PXSrchFld := pxErr_RecNotFound;
  314.                 {$else}
  315.                 pxErr := PXGetAlpha(RecHandle, FldHandle, StrFld1);
  316.                 if pxErr = pxSuccess then begin
  317.                   pxErr := PXGetAlpha(RecHandleTemp, FldHandle,
  318.                                       StrFld2);
  319.                   if pxErr = pxSuccess then begin
  320.                     { close temp record buffer }
  321.                     PXRecBufClose(RecHandleTemp);
  322.  
  323.  
  324.  
  325.  
  326.  
  327.  
  328.  
  329.  
  330.  
  331.  
  332.  
  333.  
  334.  
  335.  
  336.  
  337.  
  338.   PRODUCT  :  Paradox Engine                        NUMBER  :  1230
  339.   VERSION  :  3.0
  340.        OS  :  DOS/WIN
  341.      DATE  :  January 25, 1993                         PAGE  :  6/8
  342.  
  343.     TITLE  :  Workaround for PXSrchFld RecNotFound Problem
  344.  
  345.  
  346.  
  347.  
  348.                     if StrFld1 = StrFld2 then
  349.                       PXSrchFld := pxSuccess
  350.                     else
  351.                       PXSrchFld := pxErr_RecNotFound;
  352.                 {$endif}
  353.                     exit;
  354.                   end;
  355.                 end;
  356.               end;
  357.  
  358.               'D' : begin
  359.                 pxErr := PXGetDate(RecHandle, FldHandle, DateFld1);
  360.                 if pxErr = pxSuccess then begin
  361.                   pxErr := PXGetDate(RecHandleTemp, FldHandle,
  362.                                      DateFld2);
  363.                   if pxErr = pxSuccess then begin
  364.                     { close temp record buffer }
  365.                     PXRecBufClose(RecHandleTemp);
  366.  
  367.                     if DateFld1 = DateFld2 then
  368.                       PXSrchFld := pxSuccess
  369.                     else
  370.                       PXSrchFld := pxErr_RecNotFound;
  371.                     exit;
  372.                   end;
  373.                 end;
  374.               end;
  375.  
  376.               'N' : begin
  377.                 pxErr := PXGetDoub(RecHandle, FldHandle, NumFld1);
  378.                 if pxErr = pxSuccess then begin
  379.                   pxErr := PXGetDoub(RecHandleTemp, FldHandle,
  380.                                      NumFld2);
  381.                   if pxErr = pxSuccess then begin
  382.                     { close temp record buffer }
  383.                     PXRecBufClose(RecHandleTemp);
  384.  
  385.                     { Test if either value was blank }
  386.                     { If both are blank then treat as not equal }
  387.                     if (NumFld1 = 0) <> (NumFld2 = 0) then begin
  388.  
  389.  
  390.  
  391.  
  392.  
  393.  
  394.  
  395.  
  396.  
  397.  
  398.  
  399.  
  400.  
  401.  
  402.  
  403.  
  404.   PRODUCT  :  Paradox Engine                        NUMBER  :  1230
  405.   VERSION  :  3.0
  406.        OS  :  DOS/WIN
  407.      DATE  :  January 25, 1993                         PAGE  :  7/8
  408.  
  409.     TITLE  :  Workaround for PXSrchFld RecNotFound Problem
  410.  
  411.  
  412.  
  413.  
  414.                       PXSrchFld := pxErr_RecNotFound;
  415.                       Exit;
  416.                     end;
  417.  
  418.                     { We use this method for comparing floating }
  419.                     { point numbers because of the way floats are }
  420.                     { represented in binary. Example, we cannot }
  421.                     { guarantee if (.100 - .23) = .67 is going to }
  422.                     { return true because .23 might be .229998 as }
  423.                     { represented internally. }
  424.  
  425.                     if NumFld1 <> NumFld2 then
  426.                       PXSrchFld := pxSuccess
  427.                     else
  428.                       PXSrchFld := pxErr_RecNotFound;
  429.                     exit;
  430.  
  431.                     NumFld1 := Abs(NumFld1 - NumFld2);
  432.  
  433.                     if NumFld1 < SigFig then
  434.                       PXSrchFld := pxSuccess
  435.                     else
  436.                       PXSrchFld := pxErr_RecNotFound;
  437.                   end;
  438.                 end;
  439.               end;
  440.  
  441.               'S' : begin
  442.                 pxErr := PXGetShort(RecHandle, FldHandle,
  443.                                     ShortFld1);
  444.                 if pxErr = pxSuccess then begin
  445.                   pxErr := PXGetShort(RecHandleTemp, FldHandle,
  446.                                       ShortFld2);
  447.                   if pxErr = pxSuccess then begin
  448.                     { close temp record buffer }
  449.                     PXRecBufClose(RecHandleTemp);
  450.  
  451.                     if ShortFld1 = ShortFld2 then
  452.                       PXSrchFld := pxSuccess
  453.                     else
  454.  
  455.  
  456.  
  457.  
  458.  
  459.  
  460.  
  461.  
  462.  
  463.  
  464.  
  465.  
  466.  
  467.  
  468.  
  469.  
  470.   PRODUCT  :  Paradox Engine                        NUMBER  :  1230
  471.   VERSION  :  3.0
  472.        OS  :  DOS/WIN
  473.      DATE  :  January 25, 1993                         PAGE  :  8/8
  474.  
  475.     TITLE  :  Workaround for PXSrchFld RecNotFound Problem
  476.  
  477.  
  478.  
  479.  
  480.                       PXSrchFld := pxErr_RecNotFound;
  481.                     exit;
  482.                   end;
  483.                 end;
  484.  
  485.               end;
  486.             end;
  487.           end;
  488.  
  489.       if pxErr = pxErr_EndOfTable then
  490.         if Mode = SearchFirst then begin
  491.           { Uncomment out the next line of you want }
  492.           { pxErr_RecNotFound returned by SearchFirst if the }
  493.           { cursor is left at the end of the table (PXSrchFld }
  494.           { with the SearchFirst parameter will not return }
  495.           { pxErr_EndOfTable). }
  496.           {
  497.           PXSrchFld := pxErr_RecNotFound;
  498.           Exit;
  499.           }
  500.         end
  501.         else begin
  502.           PXSrchFld := pxErr;
  503.           Exit;
  504.         end;
  505.       end;
  506.     end;
  507.  
  508.     PXSrchFld := pxErr;
  509.  
  510.   end;
  511.  
  512.   end.
  513.  
  514.   DISCLAIMER: You have the right to use this technical information
  515.   subject to the terms of the No-Nonsense License Statement that
  516.   you received with the Borland product to which this information
  517.   pertains.
  518.  
  519.  
  520.  
  521.  
  522.  
  523.  
  524.  
  525.  
  526.  
  527.  
  528.  
  529.